package cloud.lysky.java.on.concurrent.lock.readwritelock;

/**
 * @author luoly
 * @describe 演示读写锁的使用
 * @date 2023-04-30 20:12
 **/

import java.util.HashMap;
import java.util.Map;

/**
 * 假设现在有一个在线购物网站，有一个商品库存系统，记录着每个商品的库存量。
 * 在高峰期，可能会有成千上万的用户同时查询商品库存，而只有少量的用户会修改库存。
 * 因此，为了提高性能，我们可以使用ReentrantReadWriteLock来实现读写分离
 */
public class ReadWriteLockDemo {
    // 代表商品库存
    private final Map<String, Integer> prods = new HashMap<>();
    // 读写锁
//    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    // 使用自己实现的读写锁
    private final MyReadWriteLock lock = new MyReadWriteLock();

    // 查询商品库存
    public int getStock(String prodId){
        // 读锁
        //lock.readLock().lock();
        lock.readLock();
        try {
            Integer stock = prods.get(prodId);
            return stock == null ? 0 : stock;
        } finally {
            //lock.unlock();
            lock.readUnlock();
        }
    }
    // 更新商品库存
    public void setStock(String prodId, int stock){
        // 写锁
        // lock.writeLock().lock();
        lock.writeLock();
        try {
            prods.put(prodId, stock);
        } finally {
            //lock.writeLock().unlock();
            lock.writeUnlock();
        }
    }

    public static void main(String[] args) {
        // 开启多个线程测试
        ReadWriteLockDemo demo = new ReadWriteLockDemo();
        new Thread(() -> {
            System.out.println(" 新的写请求来啦： ");
            demo.setStock("prod", 100);
            try {
                Thread.sleep(10000L);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                System.out.println(" 新的读请求来啦： " +demo.getStock("prod"));
            }).start();
        }
    }
}
